/*
 * SonarQube
 * Copyright (C) 2009-2021 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.sonar.api.web;

import org.sonar.api.ExtensionPoint;
import org.sonar.api.server.ServerSide;

/**
 * Extension point to support a web analytics tool like Matomo or
 * Google Analytics in the webapp.
 *
 * <p>See the method {@link #getUrlPathToJs()} for the details about specification.</p>
 *
 * <p>
 * Example of implementation with a {@link org.sonar.api.server.ws.WebService}:
 * </p>
 * <pre>
 * import java.io.IOException;
 * import java.io.OutputStream;
 * import java.nio.charset.StandardCharsets;
 * import org.apache.commons.io.IOUtils;
 * import org.sonar.api.server.ws.Request;
 * import org.sonar.api.server.ws.RequestHandler;
 * import org.sonar.api.server.ws.Response;
 * import org.sonar.api.server.ws.WebService;
 * import org.sonar.api.web.WebAnalytics;
 *
 * public class MyWebAnalytics implements WebAnalytics, WebService, RequestHandler {
 *
 *   {@literal @}Override
 *   public String getUrlPathToJs() {
 *     return "api/myplugin/analytics";
 *   }
 *
 *   {@literal @}Override
 *   public void define(Context context) {
 *     NewController controller = context.createController("api/myplugin");
 *     controller.createAction("analytics")
 *       .setInternal(false)
 *       .setHandler(this);
 *     controller.done();
 *   }
 *
 *   {@literal @}Override
 *   public void handle(Request request, Response response) throws IOException {
 *     try (OutputStream output = response.stream()
 *       .setMediaType("application/javascript")
 *       .output()) {
 *       IOUtils.write("{replace with the javascript content}", output, StandardCharsets.UTF_8);
 *     }
 *   }
 * }
 * </pre>
 *
 * @since 7.8
 */
@ServerSide
@ExtensionPoint
public interface WebAnalytics {

  /**
   * Returns the URL path to the Javascript file that will be loaded by the webapp. File must be
   * provided by SonarQube server and can't be located outside.
   *
   * <p>
   * The returned path must not start with a slash '/' and must not contain ".." or "://".
   * </p>
   *
   * <p>
   * Examples:
   * <ul>
   *  <li>"api/google/analytics" if file is generated by a {@link org.sonar.api.server.ws.WebService}.</li>
   *  <li>"static/myplugin/analytics.js" if file is bundled with the plugin with key "myplugin"
   *   (note that in this case the file in the plugin JAR is "static/analytics.js").</li>
   * </ul>
   * </p>
   *
   * <p>
   * Webapp does not load the Javascript file if the URL does not return HTTP code 200.
   * </p>
   *
   * <p>
   * The Javascript file is composed of two parts:
   * <ul>
   *   <li>the global code that is executed when the browser loads the webapp</li>
   *   <li>the handler that is executed by the webapp when page is changed. See function "window.setWebAnalyticsPageChangeHandler()".</li>
   * </ul>
   * </p>
   * Example for Matomo:
   *
   * <pre>
   * var _paq = window._paq || [];
   * // tracker methods like "setCustomDimension" should be called before "trackPageView"
   * _paq.push(["trackPageView"]);
   * _paq.push(["enableLinkTracking"]);
   * (function() {
   *   var u = "https://me.matomo.cloud/";
   *   _paq.push(["setTrackerUrl", u + "matomo.php"]);
   *   _paq.push(["setSiteId", "12345"]);
   *   var d = document,
   *     g = d.createElement("script"),
   *     s = d.getElementsByTagName("script")[0];
   *   g.type = "text/javascript";
   *   g.async = true;
   *   g.defer = true;
   *   g.src = "//cdn.matomo.cloud/me.matomo.cloud/matomo.js";
   *   s.parentNode.insertBefore(g, s);
   * })();
   *
   * window.setWebAnalyticsPageChangeHandler(function(pathname) {
   *   _paq.push(["setCustomUrl", pathname]);
   *   _paq.push(["setDocumentTitle", document.title]);
   *   _paq.push(["trackPageView"]);
   * });
   * </pre>
   */
  String getUrlPathToJs();

}
